package otSpaces.client.demo;

import java.net.PasswordAuthentication;
import java.nio.ByteBuffer;
import java.util.Random;
import java.util.logging.Logger;

import javax.swing.JOptionPane;

import otSpaces.client.SimpleOtClient;

import com.sun.sgs.client.ClientChannel;
import com.sun.sgs.client.ClientChannelListener;

public class SimpleClientDemo implements SimpleOtClient.Listener {

	public static final Logger LOG = Logger.getLogger(SimpleClientDemo.class
			.getName());

	private static final long serialVersionUID = 1L;

	public static void main(String... args) {

		// prompt for host:port values
		final Object result = JOptionPane.showInputDialog(null,
				"Connect to server", "Ready?", JOptionPane.PLAIN_MESSAGE, null,
				null, "localhost:62964");

		// if they hit "Cancel" then quit ...
		if (result == null) {
			System.exit(0);
		}

		// they did not hit cancel, so ...
		try {

			// create our client (won't throw an exception)
			final SimpleClientDemo client = new SimpleClientDemo();

			// lock on the client (see the getPasswordAuthentication() method)
			synchronized (client) {

				// run the login with that string
				client._simpleOtClient.login(result.toString());

				// wait for the getPasswordAuthentication() method to call
				client.wait(10000L);
			}

			// now put up an "OK to Quit?" message. RD will exit when nobody is
			// running anymore so we need something to keep him alive
			JOptionPane.showMessageDialog(null, "Ok to finish?");

		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	// this is our clientObject
	private final SimpleOtClient _simpleOtClient = new SimpleOtClient(this);

	@Override
	public void disconnected(boolean graceful, String reason) {
		// if we're disconnected
		LOG.info("Grace" + (graceful ? "fully" : "lessly") + " because `"
				+ reason + "`");
		System.exit(0);
	}

	@Override
	public PasswordAuthentication getPasswordAuthentication() {
		synchronized (this) {

			// tell the main that they can continue (once we're out of this
			// block)
			notify();

			// return a semi-random client name
			return new PasswordAuthentication(getClass().getName()
					+ (new Random().nextLong()), new char[0]);
		}
	}

	@Override
	public ClientChannelListener joinedChannel(ClientChannel channel) {

		/*
		 * TopicSpace channels are handled by an outer layer, so we don't need
		 * to worry about them here.
		 * 
		 * Since this demo doesn't support any other type of channel, we throw
		 * the exception.
		 */

		throw new UnsupportedOperationException();
	}

	@Override
	public ClientChannelListener joinedTopic(final String topicSpaceName,
			ClientChannel channel) {

		// throw up a message about the topicJoin
		LOG.info("Joined Topic `" + channel.getName() + "` in TopicSpace `"
				+ topicSpaceName + "`");

		// return a generic listener
		return new ClientChannelListener() {

			@Override
			public void leftChannel(ClientChannel channel) {

				// log a message about leaving the channel
				LOG.info("Left Topic `" + channel.getName()
						+ "` in TopicSpace `" + topicSpaceName + "`");

			}

			@Override
			public void receivedMessage(ClientChannel channel,
					ByteBuffer message) {

				// log a message about the data recieved
				LOG.info("Recieved " + message.remaining()
						+ " bytes on Topic `" + channel.getName()
						+ "` in TopicSpace `" + topicSpaceName + "`");
			}

		};
	}

	@Override
	public void joinedTopicSpace(String topicSpaceName) {

		// log a message about joining the TopicSpace
		LOG.info("Joined TopicSpace `" + topicSpaceName + "`");
	}

	@Override
	public void leftTopicSpace(String topicSpaceName) {

		// log a message about leaving the TopicSpace
		LOG.info("Left TopicSpace `" + topicSpaceName + "`");

	}

	@Override
	public void loggedIn() {

		// just log that we have logged in
		LOG.info("");
	}

	@Override
	public void loginFailed(String reason) {

		// log that we have failed to login, and print out the reason
		LOG.info("Because `" + reason + "`");
		System.exit(0);
	}

	@Override
	public void receivedMessage(ByteBuffer message) {

		/*
		 * Since this demo doesn't support direct communication, we throw the
		 * exception.
		 */
		throw new UnsupportedOperationException(
				"TODO Auto-generated method stub");
	}

	@Override
	public void reconnected() {

		// just log that we have reconnected
		LOG.info("");
	}

	@Override
	public void reconnecting() {
		// just log that we are reconnecting
		LOG.info("");
	}

}
